package com.fly.db.util;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.fly.db.FlySQLiteOpenHelper;
import com.fly.db.entity.DBEntity;
import com.fly.db.entity.Table;
import com.fly.db.exception.SQLErrorException;
import com.fly.db.exception.TableColumnValueNotMatch;
import com.fly.db.exception.TableNoExistException;

import java.util.ArrayList;
import java.util.Map;

/**
 * Created with Android Studio.
 * Package_Name：com.fly.db.util
 * Project_Name：DBExample
 * User：郭鹏飞
 * Date：2015/12/17
 * Email：love518420@foxmail.com
 * Description：数据表工具(新建表，删除表，清空表)
 */
public class TableUtil {

    private static ArrayList<String> tableNames;
    private static DBEntity dbEntity;

    private TableUtil() {
    }

    public static void initDBEntity(DBEntity dbEntity) {
        TableUtil.dbEntity = dbEntity;
        TableUtil.tableNames = new ArrayList<>();
        for (Table table :
                dbEntity.getTables()) {
            tableNames.add(table.getTableName());
        }
    }

    /**
     * 创建表
     *
     * @param db          SQLiteDatabase
     * @param tableName   表名
     * @param columnNames 列名+类型
     */
    public synchronized static void createTable(@NonNull SQLiteDatabase db,
                                                @NonNull String tableName, @NonNull Map<String, String> columnNames) {
        if (TextUtils.isEmpty(tableName) || columnNames.isEmpty()) {
            throw new NullPointerException("参数有空数据");
        }
        StringBuilder sb = new StringBuilder();
        sb.append("( ");
        for (Map.Entry<String, String> entry : columnNames.entrySet()) {
            sb.append(entry.getKey());
            sb.append(" ");
            sb.append(entry.getValue());
            sb.append(",");
        }
        // 删除最后一个多余的 ,
        sb = sb.delete(sb.length() - 1, sb.length());
        sb.append(" )");
        String sql = "create table " + tableName + sb.toString();
        db.execSQL(sql);
    }

    /**
     * 执行insert语句
     *
     * @param flySQLiteOpenHelper FlySQLiteOpenHelper
     * @param tableName           表名
     * @param columns             列
     * @param values              值
     */
    public synchronized static void invokeInsertSql(
            @NonNull FlySQLiteOpenHelper flySQLiteOpenHelper, @NonNull String tableName,
            @Nullable String columns[], Object values[]) {
        if (columns == null || columns.length <= 0) { // 此时默认为所有列赋值
            // 根据表名 获取所有列
            Map<String, String> column = dbEntity.getTable(tableName).getColumns();
            columns = new String[column.size()];
            int index = 0;
            for (Map.Entry<String, String> entry : column.entrySet()) {
                columns[index++] = entry.getKey();
            }
        }
        // 比较列数与值数是否匹配
        if (columns.length != values.length) {
            throw new TableColumnValueNotMatch();
        }
        // 拼接sql语句
        StringBuilder sbColumn = new StringBuilder();
        for (String column : columns) {
            sbColumn.append(column);
            sbColumn.append(",");
        }
        // 删除最后一个多余的
        sbColumn = sbColumn.delete(sbColumn.length() - 1, sbColumn.length());
        StringBuilder sbValue = new StringBuilder();
        for (Object value : values) {
            sbValue.append("?");
            sbValue.append(",");
        }
        // 删除最后一个多余的 &
        sbValue = sbValue.delete(sbValue.length() - 1, sbValue.length());
        String sql = "insert into " + tableName + "(" + sbColumn.toString() + ")"
                + "values (" + sbValue.toString() + ")";
        SQLiteDatabase db = flySQLiteOpenHelper.openDatabase();
        db.execSQL(sql, values);
        flySQLiteOpenHelper.closeDatabase();
    }

    /**
     * 执行delete语句
     *
     * @param flySQLiteOpenHelper FlySQLiteOpenHelper
     * @param tableName           表名
     * @param conditionColumns    where条件列
     * @param values              值
     */
    public synchronized static void invokeDeleteSql(@NonNull FlySQLiteOpenHelper flySQLiteOpenHelper,
                                                    @NonNull String tableName, @Nullable String conditionColumns[],
                                                    @Nullable String values[]) {
        if (conditionColumns == null || conditionColumns.length <= 0
                || values == null || values.length <= 0) {
            deleteTable(flySQLiteOpenHelper, tableName);
            return;
        }
        if (values.length != conditionColumns.length) {
            throw new TableColumnValueNotMatch();
        }
        // 拼接sql语句
        StringBuilder sb = new StringBuilder();
        for (String condition :
                conditionColumns) {
            sb.append(condition);
            sb.append("=");
            sb.append("?");
            sb.append(",");
        }
        // 删除最后一个多余的
        sb = sb.delete(sb.length() - 1, sb.length());
        String sql = "delete from " + tableName + " where " + sb.toString();
        SQLiteDatabase db = flySQLiteOpenHelper.openDatabase();
        db.execSQL(sql, values);
        flySQLiteOpenHelper.closeDatabase();
    }

    public synchronized static void invokeUpdateSql(FlySQLiteOpenHelper flySQLiteOpenHelper,
                                                    String tableName,
                                                    String valueColumns[],
                                                    Object columnValues[],
                                                    String conditionColumns[],
                                                    Object conditionValues[]) {
        Object values[] = new Object[columnValues.length + conditionValues.length];

        // TODO: 2016/1/26
        String sql = "update " + tableName + "set " + " where ";
    }

    /**
     * 执行select语句 注意关闭Cursor
     *
     * @param flySQLiteOpenHelper FlySQLiteOpenHelper
     * @param tableName           表名
     * @param valueColumns        选择的列
     * @param conditionColumns    条件列
     * @param values              值
     * @return Cursor 可能为空
     */
    public synchronized static Cursor invokeSelectSql(@NonNull FlySQLiteOpenHelper flySQLiteOpenHelper,
                                                      @NonNull String tableName,
                                                      @Nullable String valueColumns[],
                                                      @Nullable String conditionColumns[],
                                                      @Nullable String values[]) {
        StringBuilder valueSB = new StringBuilder();
        // 拼接读取列
        if (valueColumns == null || valueColumns.length <= 0) {
            valueSB.append("*");
        } else {
            for (String valueColumn :
                    valueColumns) {
                valueSB.append(valueColumn);
                valueSB.append(",");
            }
            valueSB = valueSB.delete(valueSB.length() - 1, valueSB.length());
        }

        String sql = "select " + valueSB.toString() + " from " + tableName;
        if (values != null && values.length > 0) {
            if (conditionColumns == null) {
                throw new SQLErrorException();
            }
            if (values.length == conditionColumns.length) {
                StringBuilder whereSB = new StringBuilder();
                whereSB.append(" ");
                whereSB.append("where");
                whereSB.append(" ");
                for (String condition :
                        conditionColumns) {
                    whereSB.append(condition);
                    whereSB.append("=");
                    whereSB.append("?");
                    whereSB.append(",");
                }
                whereSB = whereSB.delete(whereSB.length() - 1, whereSB.length());
                sql += whereSB.toString();
            } else {
                throw new TableColumnValueNotMatch();
            }
        } else {
            if (conditionColumns != null && conditionColumns.length > 0) {
                throw new SQLErrorException();
            }
        }

        SQLiteDatabase db = flySQLiteOpenHelper.openDatabase();
        return db.rawQuery(sql, values);
    }

    /**
     * 删除表数据库中不再有该表存在
     *
     * @param flySQLiteOpenHelper FlySQLiteOpenHelper
     * @param tableName           表名
     */
    public synchronized static void dropTable(FlySQLiteOpenHelper flySQLiteOpenHelper, String tableName) {
        if (flySQLiteOpenHelper == null || TextUtils.isEmpty(tableName)) {
            throw new NullPointerException("参数有空数据");
        }
        SQLiteDatabase db = flySQLiteOpenHelper.openDatabase();
        if (!tableNames.contains(tableName)) {
            throw new TableNoExistException();
        }
        String sql = "drop table " + tableName;
        db.execSQL(sql);
        flySQLiteOpenHelper.closeDatabase();
        // 移除被删除的表
        dbEntity.remove(tableName);
        tableNames.remove(tableName);
    }

    /**
     * 清空数据表里面的所有数据数据库中还存在该表
     *
     * @param flySQLiteOpenHelper FlySQLiteOpenHelper
     * @param tableName           表名
     */
    public synchronized static void deleteTable(FlySQLiteOpenHelper flySQLiteOpenHelper, String tableName) {
        if (flySQLiteOpenHelper == null || TextUtils.isEmpty(tableName)) {
            throw new NullPointerException("参数有空数据");
        }
        SQLiteDatabase db = flySQLiteOpenHelper.openDatabase();
        if (!tableNames.contains(tableName)) {
            throw new TableNoExistException();
        }
        db.delete(tableName, null, null);
        flySQLiteOpenHelper.closeDatabase();
    }

    /**
     * 清空数据库里面的表
     *
     * @param flySQLiteOpenHelper FlySQLiteOpenHelper
     */
    public synchronized static void clearDBTables(FlySQLiteOpenHelper flySQLiteOpenHelper) {
        for (String tableName :
                tableNames) {
            dropTable(flySQLiteOpenHelper, tableName);
        }
    }

}
